package br.ufpi.persistenci;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.metadata.ClassMetadata;

import br.ufpi.domain.Pergunta;
import br.ufpi.domain.Resposta;
import br.ufpi.domain.Usuario;




public class HibernateUtil{
	private static final SessionFactory sessionFactory;
	private static final ThreadLocal<Session> threadDeSessao = new ThreadLocal<Session>();
	private static final ThreadLocal<Transaction> threadDeTransacao = new ThreadLocal<Transaction>();

	static {
		try {
			AnnotationConfiguration cfg = new AnnotationConfiguration()
					.configure();

			cfg = getEntityPersistence(cfg);

			sessionFactory = cfg.buildSessionFactory();
		} catch (Throwable ex) {
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public static AnnotationConfiguration getEntityPersistence(
			AnnotationConfiguration cfg) {
		// Adiciona as Classes Mapeadas
		cfg.addAnnotatedClass(Pergunta.class);
		cfg.addAnnotatedClass(Usuario.class);
		cfg.addAnnotatedClass(Resposta.class);
		return cfg;
	}

	public static Session getSessao() throws HibernateException {
		if (threadDeSessao.get() == null) {
			Session sessao = sessionFactory.openSession();
			Transaction tran = sessao.beginTransaction();
			threadDeSessao.set(sessao);
			threadDeTransacao.set(tran);

		}
		return threadDeSessao.get();
	}

	@SuppressWarnings("unused")
	public static Transaction getTransacao() throws HibernateException {
		if (threadDeSessao.get() == null) {
			// Inicializa a sessao e a transacao
			Session sessao = getSessao();
		}
		return threadDeTransacao.get();
	}

	public static void fecharSessao() {
		try {
			if (getSessao() != null) {
				getSessao().close();
			}
		} finally {
			threadDeSessao.set(null);
			threadDeTransacao.set(null);
		}
	}

	public static void confirmarTransacao() {
		try {
			if (getTransacao() != null) {
				getTransacao().commit();
			}
		} finally {
			fecharSessao();
		}
	}

	public static void cancelarTransacao() {
		try {
			if (getTransacao() != null)
				getTransacao().rollback();
		} finally {
			fecharSessao();
		}
	}

	static ClassMetadata getClassMetadata(br.ufpi.domain.Persistente objeto) {
		return sessionFactory.getClassMetadata(objeto.getClass());
	}

}
